
package ploy.lang;

import java.util.*;
import java.io.*;
import java.math.*;

public class Symbol extends DynamicObject
    implements Comparable<Symbol> {
    
    public static String jvmClass = "ploy/lang/Symbol";
    public static String jvmType = "L" + jvmClass + ";";    

    private static int currentSymbolNumber = 0;

    private static Map<String, Integer> stringToSymbolNumberMap =
	new Hashtable<String, Integer>();

    private static Map<Integer, String> symbolNumberToStringMap =
	new Hashtable<Integer, String>();

    private static synchronized int newSymbolNumber() {
	return currentSymbolNumber++;
    }

    private static synchronized int stringToSymbolNumber( String s ) {
	if ( stringToSymbolNumberMap.containsKey( s ) )
	    return stringToSymbolNumberMap.get( s );
	else {
	    int newSymbolNumber = newSymbolNumber();
	    stringToSymbolNumberMap.put( s, newSymbolNumber );
	    symbolNumberToStringMap.put( newSymbolNumber, s );
	    return newSymbolNumber;
	}
    }

    private static int currentGenSymNumber = 0;

    public static Symbol genSym( ) {
	String s;
	
	do {
	    s = "g" + Integer.toString(currentGenSymNumber++);
	} while ( stringToSymbolNumberMap.containsKey( s ) );
	
	return new Symbol( s );
    }

    public boolean isSymbol() { return true; }

    protected int symbolNumber;
    
    public Symbol( String s ) {
	symbolNumber = stringToSymbolNumber( s );
    }

    public String toString( ) {
	return symbolNumberToStringMap.get( symbolNumber );
    }

    public int hashCode( ) {
	return symbolNumber;
    }

    public boolean equals( Object o ) {
	return ( ( o instanceof Symbol ) && 
		 ( symbolNumber == ((Symbol)o).symbolNumber ) );
    }

    public int compareTo( Symbol s ) {
	return new Integer(symbolNumber).compareTo( s.symbolNumber );
    }

}

